package com.navinfo.platform.trip.common.arithmetic;

import com.navinfo.platform.trip.common.arithmetic.annotation.Arithmetic;
import com.navinfo.platform.trip.common.arithmetic.data.CommonData;
import com.navinfo.platform.trip.common.arithmetic.data.OuterStatisticData;
import com.navinfo.platform.trip.common.arithmetic.var.VarCommonNumberStatus;
import com.navinfo.platform.trip.common.arithmetic.enums.EventType;
import com.navinfo.platform.trip.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.platform.trip.common.config.ConfigMap;
import com.navinfo.platform.trip.common.util.ArithmeticUtils;

import java.util.Optional;

/**
 * 东风新版，冷车运行算法<br/>
 * 1.平台收到车辆上电ON档信号时开始；<br/>
 * 2.T-BOX上传发动机水温低于60度；<br/>
 * 3.当车速大于60km/h或发动机转速大于1700rpm，判断持续时间大于3分钟，识别为一次事件<br/>
 * 4.行程结束，累计计算冷车运行事件次数（记录1次事件）和  油耗:【发动机水温小于60度且（车速>60km/h或发动机转速>1700rpm）】时候的累计油耗。以及冷车运行累积时间<br/>
 * 依赖{@link Mileage}里程油耗算法<br/>
 * 输出：统计、事件<br/>
 * @author web
 * @data: 2020-0-19
 */
@Arithmetic(name = "东风新版-冷车运行算法")
public class DrivingCold_DFN extends AbstractArithmetic<VarCommonNumberStatus> {
    /**
     * 事件类型
     */
    private static final EventType EVENT_TYPE = EventType.drivingCold_DFN;
    /**
     * 发动机水温阈值，单位度，默认60
     */
    private int temperatureThreshold = ConfigMap.getInteger("DFN_Cold_Running_Tem_Threshold");
    /**
     * 速度阈值，单位km/h，默认60
     */
    private int speedThreshold = ConfigMap.getInteger("DFN_Cold_Running_Speed_Threshold");
    /**
     * 转速阈值，单位RPM，默认1700
     */
    private int rotationThreshold = ConfigMap.getInteger("DFN_Cold_Running_Rotation_Threshold");
    /**
     * 持续时长阈值，单位ms，默认180 * 1000
     */
    private int durationThreshold = 1000 * ConfigMap.getInteger("DFN_Cold_Running_Duration_Threshold");

    /**
     * 判断当前是否为冷车运行
     */
    boolean isDrivingCold() {
        CommonData commonData = getCommonData();
        return commonData.isAcc() && commonData.getWaterTemp()<temperatureThreshold &&
                (commonData.getSpeedKmh()>speedThreshold || commonData.getRotation()>rotationThreshold);
    }

    @Override
    public void calculate() {
        logger.debug("进入东风新版冷车运行算法.");
        if(null == getCommonData().getWaterTemp()){
            return;
        }

        VarCommonNumberStatus var = getObj();
        boolean preStatus = var.isPreStatus();
        boolean curStatus = isDrivingCold();

        //算法计算
        switch (getEventStatus(preStatus, curStatus)) {
            case START:
                startEventData(EVENT_TYPE);
                break;
            case IN:
                calcEventData(EVENT_TYPE);
                break;
            case END:
                calcEventData(EVENT_TYPE);
                endEventData();
                break;
            default:
                break;
        }

        //行程结束时要清理对应的未结束事件
        if (getCommonData().isTripLastNode()) {
            endEventData();
        }

        //设置上一个点状态、供下个点计算
        var.setPreStatus(curStatus);
        logger.debug("东风新版冷车运行算法结束.");
    }

    /**
     * 处理事件的结束状态
     */
    private void endEventData() {
        endEventData(EVENT_TYPE, (eventData, drivingData) -> {
            if (Optional.ofNullable(eventData.getDuration()).orElse(0L) > durationThreshold) {
                //事件变量的累积里程油耗时长赋值到统计变量中
                VarCommonNumberStatus var = getObj();
                var.addNumber(1);
                var.addMileage(Optional.ofNullable(eventData.getExtendField05()).orElse(0.0));
                var.addFuel(Optional.ofNullable(eventData.getExtendField06()).orElse(0.0));
                var.addDuration(Optional.ofNullable(eventData.getDuration()).orElse(0L).intValue());

                //放入事件输出列表
                drivingData.addEventDataToList(eventData);
            } else {
                logger.debug("东风新版冷车运行算法时间{}ms,小于阈值{}ms，不进行统计", Optional.ofNullable(eventData.getDuration()).orElse(0L), durationThreshold);
            }
        });
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
        VarCommonNumberStatus obj = getObj();
        statisticDataOut.setColdRunningMileage_DFN(ArithmeticUtils.mileageMToM(obj.getMileage()));
        statisticDataOut.setColdRunningFuel_DFN(ArithmeticUtils.fuelMlToMl(obj.getFuel()));
        statisticDataOut.setColdRunningDuration_DFN(ArithmeticUtils.timeMsToSecond(obj.getDuration()));
        statisticDataOut.setColdRunningNumber_DFN(obj.getNumber());
    }

}
